import * as Blockly from 'blockly';

export const systemFunctionBlocks = {
  system_variable_get_history_value: {
    type: 'system_variable_get_history_value',
    message0: 'System.Variable.getHistoryValue   变量路径或变量路径数组: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: ['String', 'Array'],
      },
    ],
    message1: '                                     瞬时时间: %1',
    args1: [
      {
        type: 'input_value',
        name: 'TIME',
        check: ['String', 'Date'],
        align: 'right',
      },
    ],
    output: ['HistoryValue', 'Array'],
    colour: 290,
    tooltip: '根据变量路径和时间获取历史值',
    helpUrl: '',
  },

  // 新增的 getHistoryValues 块定义
  system_variable_get_history_values: {
    type: 'system_variable_get_history_values',
    message0: 'System.Variable.getHistoryValues   变量路径或变量路径数组: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: ['String', 'Array'],
      },
    ],
    message1: '                                       开始时间: %1',
    args1: [
      {
        type: 'input_value',
        name: 'START_TIME',
        check: ['String', 'Date'],
        align: 'right',
      },
    ],
    message2: '                                       结束时间: %1',
    args2: [
      {
        type: 'input_value',
        name: 'END_TIME',
        check: ['String', 'Date'],
        align: 'right',
      },
    ],
    message3: '                                     采样.类型: %1',
    args3: [
      {
        type: 'field_dropdown',
        name: 'SAMPLE_TYPE',
        options: [
          ['原始值(raw)', 'raw'],
          ['平均值(avg)', 'avg'],
          ['最大值(max)', 'max'],
          ['最小值(min)', 'min'],
        ],
        align: 'right',
      },
    ],
    message4: '                                     采样.周期: %1',
    args4: [
      {
        type: 'input_value',
        name: 'SAMPLE_PERIOD',
        check: 'Number',
        align: 'right',
      },
    ],
    output: 'Array',
    colour: 290,
    tooltip: '根据变量路径和时间范围获取历史值数组',
    helpUrl: '',
    inputsInline: false,
  },

  // 新增的 getQuality 块定义
  system_variable_get_quality: {
    type: 'system_variable_get_quality',
    message0: 'System.Variable.getQuality   变量路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: 'String',
      },
    ],
    output: 'String',
    colour: 290,
    tooltip: '根据变量路径获取变量的质量位',
    helpUrl: '',
  },

  // 新增的 getQualityInt 块定义
  system_variable_get_quality_int: {
    type: 'system_variable_get_quality_int',
    message0: 'System.Variable.getQualityInt   变量路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: 'String',
      },
    ],
    output: 'Number',
    colour: 290,
    tooltip: '根据变量路径获取变量的质量位整数值(Good=1, Bad=2)',
    helpUrl: '',
  },

  // 新增的 getValue 块定义
  system_variable_get_value: {
    type: 'system_variable_get_value',
    message0: 'System.Variable.getValue   变量路径或变量路径数组: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: ['String', 'Array'],
      },
    ],
    message1: '                                     默认值: %1',
    args1: [
      {
        type: 'input_value',
        name: 'DEFAULT_VALUE',
        align: 'right',
      },
    ],
    output: ['Object', 'Array'],
    colour: 290,
    tooltip:
      '根据变量路径或变量路径数组获取变量或变量数组的值，如变量无值，使用默认值代替',
    helpUrl: '',
  },

  // 新增的 isBadQuality 块定义
  system_variable_is_bad_quality: {
    type: 'system_variable_is_bad_quality',
    message0: 'System.Variable.isBadQuality   变量路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: 'String',
      },
    ],
    output: 'Boolean',
    colour: 290,
    tooltip:
      '根据变量路径判断变量的质量位是否为Bad，Bad返回true，Good返回false',
    helpUrl: '',
  },

  // 新增的 isGoodQuality 块定义
  system_variable_is_good_quality: {
    type: 'system_variable_is_good_quality',
    message0: 'System.Variable.isGoodQuality   变量路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: 'String',
      },
    ],
    output: 'Boolean',
    colour: 290,
    tooltip:
      '根据变量路径判断变量的质量位是否为Good，Good返回true，Bad返回false',
    helpUrl: '',
  },

  // 新增的 setValue 块定义
  system_variable_set_value: {
    type: 'system_variable_set_value',
    message0: 'System.Variable.setValue   变量路径或变量路径数组: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: ['String', 'Array'],
      },
    ],
    message1: '                                     设置的值: %1',
    args1: [
      {
        type: 'input_value',
        name: 'VALUE',
        align: 'right',
      },
    ],
    message2: '                                     设置选项: %1',
    args2: [
      {
        type: 'field_dropdown',
        name: 'OPTIONS_TYPE',
        options: [
          ['不设置时间和质量', 'NONE'],
          ['设置时间和质量', 'BOTH'],
          ['仅设置时间', 'TIME_ONLY'],
          ['仅设置质量', 'QUALITY_ONLY'],
        ],
        align: 'right',
      },
    ],
    message3: '                                     时间: %1',
    args3: [
      {
        type: 'input_value',
        name: 'TIME',
        check: ['String', 'Array', 'Date'],
        align: 'right',
      },
    ],
    message4: '                                     质量: %1',
    args4: [
      {
        type: 'input_value',
        name: 'QUALITY',
        check: ['String', 'Array'],
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '设置变量路径或变量路径数组的值',
    helpUrl: '',
    inputsInline: false,
    mutator: 'system_variable_set_value_mutator',
  },

  // 新增的 System.ContextState.getValue 块定义
  system_context_state_get_value: {
    type: 'system_context_state_get_value',
    message0: 'System.ContextState.getValue   状态标识: %1',
    args0: [
      {
        type: 'input_value',
        name: 'STATE_ID',
        check: 'String',
      },
    ],
    message1: '                                     默认值: %1',
    args1: [
      {
        type: 'input_value',
        name: 'DEFAULT_VALUE',
        align: 'right',
      },
    ],
    output: null, // 允许任何类型的输出
    colour: 290,
    tooltip: '根据状态标识获取状态的值，如无值，使用默认值代替',
    helpUrl: '',
  },

  // 新增的 System.ContextState.setValue 块定义
  system_context_state_set_value: {
    type: 'system_context_state_set_value',
    message0: 'System.ContextState.setValue   状态标识: %1',
    args0: [
      {
        type: 'input_value',
        name: 'STATE_ID',
        check: 'String',
      },
    ],
    message1: '                                     状态值: %1',
    args1: [
      {
        type: 'input_value',
        name: 'STATE_VALUE',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '设置状态的值',
    helpUrl: '',
  },

  // 新增的 System.Logger.log 块定义
  system_logger_log: {
    type: 'system_logger_log',
    message0: 'System.Logger.log   状态码: %1',
    args0: [
      {
        type: 'input_value',
        name: 'STATUS_CODE',
        check: 'Number',
      },
    ],
    message1: '                                     操作信息: %1',
    args1: [
      {
        type: 'input_value',
        name: 'MESSAGE',
        align: 'right',
      },
    ],
    message2: '                                     补充信息: %1',
    args2: [
      {
        type: 'input_value',
        name: 'EXTRA_INFO',
        check: 'Array',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '保存前后端脚本操作日志',
    helpUrl: '',
    mutator: 'system_logger_log_mutator',
  },

  // 新增的 System.Mimic.back 块定义
  system_mimic_back: {
    type: 'system_mimic_back',
    message0: 'System.Mimic.back   回退到上一个画面',
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '回退到上一个画面',
    helpUrl: '',
  },

  // 新增的 System.Mimic.close 块定义
  system_mimic_close: {
    type: 'system_mimic_close',
    message0: 'System.Mimic.close   关闭画面',
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '关闭画面',
    helpUrl: '',
  },

  // 新增的 System.Mimic.open 块定义
  system_mimic_open: {
    type: 'system_mimic_open',
    message0: 'System.Mimic.open   画面路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'MIMIC_PATH',
        check: 'String',
      },
    ],
    message1: '                                     画面参数: %1',
    args1: [
      {
        type: 'input_value',
        name: 'MIMIC_PARAMS',
        align: 'right',
      },
    ],
    message2: '                                     变量目录替换: %1',
    args2: [
      {
        type: 'input_value',
        name: 'PATH_REPLACEMENT',
        check: 'Object',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '打开画面，并支持传递页面参数和替换变量目录',
    helpUrl: '',
    mutator: 'system_mimic_open_mutator',
  },

  // 新增的 System.Mimic.openNewTab 块定义
  system_mimic_open_new_tab: {
    type: 'system_mimic_open_new_tab',
    message0: 'System.Mimic.openNewTab   画面路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'MIMIC_PATH',
        check: 'String',
      },
    ],
    message1: '                                     画面参数: %1',
    args1: [
      {
        type: 'input_value',
        name: 'MIMIC_PARAMS',
        align: 'right',
      },
    ],
    message2: '                                     变量目录替换: %1',
    args2: [
      {
        type: 'input_value',
        name: 'PATH_REPLACEMENT',
        check: 'Object',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '在新标签页打开画面，并支持传递页面参数和替换变量目录',
    helpUrl: '',
    mutator: 'system_mimic_open_mutator', // 复用 open 的变异器
  },

  // 新增的 System.Mimic.openOverlay 块定义
  system_mimic_open_overlay: {
    type: 'system_mimic_open_overlay',
    message0: 'System.Mimic.openOverlay   画面路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'MIMIC_PATH',
        check: 'String',
      },
    ],
    message1: '                                     左边距: %1',
    args1: [
      {
        type: 'input_value',
        name: 'LEFT',
        check: 'Number',
        align: 'right',
      },
    ],
    message2: '                                     上边距: %1',
    args2: [
      {
        type: 'input_value',
        name: 'TOP',
        check: 'Number',
        align: 'right',
      },
    ],
    message3: '                                     画面参数: %1',
    args3: [
      {
        type: 'input_value',
        name: 'MIMIC_PARAMS',
        align: 'right',
      },
    ],
    message4: '                                     变量目录替换: %1',
    args4: [
      {
        type: 'input_value',
        name: 'PATH_REPLACEMENT',
        check: 'Object',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '在覆盖窗口中打开画面，并支持传递页面参数和替换变量目录',
    helpUrl: '',
    mutator: 'system_mimic_open_overlay_mutator',
  },

  // 新增的 System.Mimic.openPopup 块定义
  system_mimic_open_popup: {
    type: 'system_mimic_open_popup',
    message0: 'System.Mimic.openPopup   画面路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'MIMIC_PATH',
        check: 'String',
      },
    ],
    message1: '                                     左边距: %1',
    args1: [
      {
        type: 'input_value',
        name: 'LEFT',
        check: 'Number',
        align: 'right',
      },
    ],
    message2: '                                     上边距: %1',
    args2: [
      {
        type: 'input_value',
        name: 'TOP',
        check: 'Number',
        align: 'right',
      },
    ],
    message3: '                                     画面参数: %1',
    args3: [
      {
        type: 'input_value',
        name: 'MIMIC_PARAMS',
        align: 'right',
      },
    ],
    message4: '                                     变量目录替换: %1',
    args4: [
      {
        type: 'input_value',
        name: 'PATH_REPLACEMENT',
        check: 'Object',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '在弹出窗口中打开画面，并支持传递页面参数和替换变量目录',
    helpUrl: '',
    mutator: 'system_mimic_open_overlay_mutator', // 复用 openOverlay 的变异器
  },

  // 新增的 System.Mimic.preload 块定义
  system_mimic_preload: {
    type: 'system_mimic_preload',
    message0: 'System.Mimic.preload   画面路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'MIMIC_PATH',
        check: 'String',
      },
    ],
    message1: '                                     画面参数: %1',
    args1: [
      {
        type: 'input_value',
        name: 'MIMIC_PARAMS',
        align: 'right',
      },
    ],
    message2: '                                     变量目录替换: %1',
    args2: [
      {
        type: 'input_value',
        name: 'PATH_REPLACEMENT',
        check: 'Object',
        align: 'right',
      },
    ],
    message3: '                                     最大预加载数量: %1',
    args3: [
      {
        type: 'input_value',
        name: 'MAX_COUNT',
        check: 'Number',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '运行画面预加载',
    helpUrl: '',
    mutator: 'system_mimic_preload_mutator',
  },

  // 新增的 System.Object.getChildNodePaths 块定义
  system_object_get_child_node_paths: {
    type: 'system_object_get_child_node_paths',
    message0: 'System.Object.getChildNodePaths   父节点路径: %1',
    args0: [
      {
        type: 'input_value',
        name: 'PARENT_PATH',
        check: ['String', 'Array'],
      },
    ],
    output: 'Array',
    colour: 290,
    tooltip: '根据父节点路径获取节点下所有子节点的路径，若无子节点则返回空数组',
    helpUrl: '',
  },

  // 新增的 System.Object.getInnerFunctionMethods 块定义
  system_object_get_inner_function_methods: {
    type: 'system_object_get_inner_function_methods',
    message0: 'System.Object.getInnerFunctionMethods   内部方法路径数组: %1',
    args0: [
      {
        type: 'input_value',
        name: 'METHOD_PATHS',
        check: 'Array',
      },
    ],
    output: 'Array',
    colour: 290,
    tooltip:
      '根据内部方法的路径数组获取方法中定义的函数数组，若无子节点则返回空数组',
    helpUrl: '',
  },

  // 新增的 System.PageVariable.getValue 块定义
  system_page_variable_get_value: {
    type: 'system_page_variable_get_value',
    message0: 'System.PageVariable.getValue   变量路径或变量路径数组: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: ['String', 'Array'],
      },
    ],
    message1: '                                     默认值: %1',
    args1: [
      {
        type: 'input_value',
        name: 'DEFAULT_VALUE',
        align: 'right',
      },
    ],
    output: ['Object', 'Array'],
    colour: 290,
    tooltip:
      '根据变量路径或变量路径数组获取变量或变量数组的值，如变量无值，使用默认值代替',
    helpUrl: '',
  },

  // 新增的 System.PageVariable.setValue 块定义
  system_page_variable_set_value: {
    type: 'system_page_variable_set_value',
    message0: 'System.PageVariable.setValue   变量路径或变量路径数组: %1',
    args0: [
      {
        type: 'input_value',
        name: 'VARIABLE_PATH',
        check: ['String', 'Array'],
      },
    ],
    message1: '                                     设置的值: %1',
    args1: [
      {
        type: 'input_value',
        name: 'VALUE',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '设置变量路径或变量路径数组的值',
    helpUrl: '',
  },

  // 新增的 System.Runtime.updateControl 块定义
  system_runtime_update_control: {
    type: 'system_runtime_update_control',
    message0: 'System.Runtime.updateControl   控件名称: %1',
    args0: [
      {
        type: 'input_value',
        name: 'CONTROL_NAME',
        check: 'String',
      },
    ],
    message1: '                                     控件属性: %1',
    args1: [
      {
        type: 'input_value',
        name: 'CONTROL_PROPERTIES',
        check: 'Object',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '修改控件属性',
    helpUrl: '',
  },

  // 新增的 System.SessionContext.getValue 块定义
  system_session_context_get_value: {
    type: 'system_session_context_get_value',
    message0: 'System.SessionContext.getValue   状态标识: %1',
    args0: [
      {
        type: 'input_value',
        name: 'STATE_ID',
        check: 'String',
      },
    ],
    message1: '                                     默认值: %1',
    args1: [
      {
        type: 'input_value',
        name: 'DEFAULT_VALUE',
        align: 'right',
      },
    ],
    output: null, // 允许任何类型的输出
    colour: 290,
    tooltip: '根据状态标识获取计算同步上下文状态的值，如无值，使用默认值代替',
    helpUrl: '',
  },

  // 新增的 System.SessionContext.setValue 块定义
  system_session_context_set_value: {
    type: 'system_session_context_set_value',
    message0: 'System.SessionContext.setValue   状态标识: %1',
    args0: [
      {
        type: 'input_value',
        name: 'STATE_ID',
        check: 'String',
      },
    ],
    message1: '                                     状态值: %1',
    args1: [
      {
        type: 'input_value',
        name: 'STATE_VALUE',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '设置计算同步上下文状态的值',
    helpUrl: '',
  },

  // 新增的 System.Utils.getUserName 块定义
  system_utils_get_user_name: {
    type: 'system_utils_get_user_name',
    message0: 'System.Utils.getUserName',
    output: 'String',
    colour: 290,
    tooltip: '获取当前登录用户的用户名',
    helpUrl: '',
  },

  // 新增的 System.Utils.redirect 块定义
  system_utils_redirect: {
    type: 'system_utils_redirect',
    message0: 'System.Utils.redirect   URL: %1',
    args0: [
      {
        type: 'input_value',
        name: 'URL',
        check: 'String',
      },
    ],
    message1: '                                     在新窗口打开: %1',
    args1: [
      {
        type: 'field_dropdown',
        name: 'NEW_TAB',
        options: [
          ['是', 'true'],
          ['否', 'false'],
        ],
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip:
      '根据设置路径进行页面跳转，如不设置ifnewTab参数，则默认在新窗口打开页面',
    helpUrl: '',
    mutator: 'system_utils_redirect_mutator',
  },

  // 新增的 System.Utils.scheduleTask 块定义
  system_utils_schedule_task: {
    type: 'system_utils_schedule_task',
    message0: 'System.Utils.scheduleTask   执行函数: %1',
    args0: [
      {
        type: 'input_value',
        name: 'FUNCTION',
        check: 'Function',
      },
    ],
    message1: '                                     延迟毫秒数: %1',
    args1: [
      {
        type: 'input_value',
        name: 'MILLISECONDS',
        check: 'Number',
        align: 'right',
      },
    ],
    previousStatement: null,
    nextStatement: null,
    colour: 290,
    tooltip: '在指定的毫秒数后调用函数，重复调用会覆盖之前发起的定时任务',
    helpUrl: '',
  },
};

// 注册文本块
export function registerSystemFunctionBlocks() {
  // 检查是否已经注册过
  let systemFunctionBlocksRegistered = false;

  // 检查是否存在已注册的块
  const blockTypes = [
    'system_variable_get_history_value',
    'system_variable_get_history_values',
    'system_variable_get_quality',
    'system_variable_get_quality_int',
    'system_variable_get_value',
    'system_variable_is_bad_quality',
    'system_variable_is_good_quality',
    'system_variable_set_value',
    'system_context_state_get_value',
    'system_context_state_set_value',
    'system_logger_log',
    'system_mimic_back',
    'system_mimic_close',
    'system_mimic_open',
    'system_mimic_open_new_tab',
    'system_mimic_open_overlay',
    'system_mimic_open_popup',
    'system_mimic_preload',
    'system_object_get_child_node_paths',
    'system_object_get_inner_function_methods',
    'system_page_variable_get_value',
    'system_page_variable_set_value',
    'system_runtime_update_control',
    'system_session_context_get_value',
    'system_session_context_set_value',
    'system_utils_get_user_name',
    'system_utils_redirect',
    'system_utils_schedule_task',
  ];

  // 检查是否存在已注册的块
  const existingBlocks = blockTypes.filter(type => Blockly.Blocks[type]);
  if (existingBlocks.length > 0) {
    console.log(`Some system function blocks already exist: ${existingBlocks.join(', ')}`);
  }

  // 注册块
  const blocksToRegister = blockTypes
    .filter(type => !Blockly.Blocks[type])
    .map(type => {
      // 使用 systemFunctionBlocks 对象来获取块定义
      return systemFunctionBlocks[type as keyof typeof systemFunctionBlocks];
    });

  if (blocksToRegister.length > 0) {
    Blockly.common.defineBlocks(
      Blockly.common.createBlockDefinitionsFromJsonArray(blocksToRegister)
    );
    console.log(`Registered ${blocksToRegister.length} system function blocks`);
  } else {
    console.log('All system function blocks already exist, skipping registration');
  }

  // 标记为已注册
  systemFunctionBlocksRegistered = true;

  // 全局跟踪变异器注册状态
  let mutatorsRegistered = false;

  // 定义所有变异器
  const setValueMutator = {
    mutationToDom: function (this: Blockly.Block) {
      const container = Blockly.utils.xml.createElement('mutation');
      const optionsType = (this as any).getFieldValue('OPTIONS_TYPE');
      container.setAttribute('options_type', optionsType);
      return container;
    },

    domToMutation: function (this: Blockly.Block, xmlElement: Element) {
      const optionsType = xmlElement.getAttribute('options_type') || 'NONE';
      (this as any).updateShape_(optionsType);
    },

    updateShape_: function (this: Blockly.Block, optionsType: string) {
      // 移除现有的时间和质量输入（如果存在）
      if ((this as any).getInput('TIME')) {
        (this as any).removeInput('TIME');
      }
      if ((this as any).getInput('QUALITY')) {
        (this as any).removeInput('QUALITY');
      }

      // 根据选项类型添加相应的输入
      if (optionsType === 'BOTH' || optionsType === 'TIME_ONLY') {
        (this as any).appendValueInput('TIME')
          .setCheck(['String', 'Array', 'Date'])
          .setAlign(1)
          .appendField('                                     时间:');
      }

      if (optionsType === 'BOTH' || optionsType === 'QUALITY_ONLY') {
        (this as any).appendValueInput('QUALITY')
          .setCheck(['String', 'Array'])
          .setAlign(1)
          .appendField('                                     质量:');
      }
    },

    onchange: function (this: Blockly.Block, event: Blockly.Events.BlockChange) {
      if (
        event.type === Blockly.Events.BLOCK_CHANGE &&
        event.blockId === (this as any).id &&
        event.name === 'OPTIONS_TYPE'
      ) {
        // 当选项类型改变时，更新形状
        (this as any).updateShape_(event.newValue);
      }
    },
  };

  const loggerLogMutator = {
    mutationToDom: function (this: Blockly.Block) {
      const container = Blockly.utils.xml.createElement('mutation');
      const hasExtraInfo = (this as any).getInput('EXTRA_INFO') !== null;
      container.setAttribute('has_extra_info', hasExtraInfo ? 'true' : 'false');
      return container;
    },

    domToMutation: function (this: Blockly.Block, xmlElement: Element) {
      const hasExtraInfo = xmlElement.getAttribute('has_extra_info') === 'true';
      (this as any).updateShape_(hasExtraInfo);
    },

    updateShape_: function (this: Blockly.Block, hasExtraInfo: boolean) {
      // 移除现有的补充信息输入（如果存在）
      if ((this as any).getInput('EXTRA_INFO')) {
        (this as any).removeInput('EXTRA_INFO');
      }

      // 如果需要补充信息，添加输入
      if (hasExtraInfo) {
        (this as any).appendValueInput('EXTRA_INFO')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     补充信息:');
      }
    },

    decompose: function (this: Blockly.Block, workspace: Blockly.Workspace) {
      const containerBlock = workspace.newBlock('logger_log_container');
      (containerBlock as any).initSvg();

      const hasExtraInfo = (this as any).getInput('EXTRA_INFO') !== null;
      (containerBlock as any).setFieldValue(
        hasExtraInfo ? 'TRUE' : 'FALSE',
        'HAS_EXTRA_INFO'
      );

      return containerBlock;
    },

    compose: function (
      this: Blockly.Block,
      containerBlock: Blockly.Block
    ) {
      const hasExtraInfo = (containerBlock as any).getFieldValue('HAS_EXTRA_INFO') ===
        'TRUE';
      (this as any).updateShape_(hasExtraInfo);
    },
  };

  const mimicOpenMutator = {
    mutationToDom: function (this: Blockly.Block) {
      const container = Blockly.utils.xml.createElement('mutation');
      const hasParams = (this as any).getInput('MIMIC_PARAMS') !== null;
      const hasPathReplacement = (this as any).getInput('PATH_REPLACEMENT') !== null;
      container.setAttribute('has_params', hasParams ? 'true' : 'false');
      container.setAttribute(
        'has_path_replacement',
        hasPathReplacement ? 'true' : 'false'
      );
      return container;
    },

    domToMutation: function (this: Blockly.Block, xmlElement: Element) {
      const hasParams = xmlElement.getAttribute('has_params') === 'true';
      const hasPathReplacement =
        xmlElement.getAttribute('has_path_replacement') === 'true';
      (this as any).updateShape_(hasParams, hasPathReplacement);
    },

    updateShape_: function (
      this: Blockly.Block,
      hasParams: boolean,
      hasPathReplacement: boolean
    ) {
      // 移除现有的参数和变量目录替换输入（如果存在）
      if ((this as any).getInput('MIMIC_PARAMS')) {
        (this as any).removeInput('MIMIC_PARAMS');
      }
      if ((this as any).getInput('PATH_REPLACEMENT')) {
        (this as any).removeInput('PATH_REPLACEMENT');
      }

      // 如果需要参数，添加输入
      if (hasParams) {
        (this as any).appendValueInput('MIMIC_PARAMS')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     画面参数:');
      }

      // 如果需要变量目录替换，添加输入
      if (hasPathReplacement) {
        (this as any).appendValueInput('PATH_REPLACEMENT')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     变量目录替换:');
      }
    },

    decompose: function (this: Blockly.Block, workspace: Blockly.Workspace) {
      const containerBlock = workspace.newBlock('mimic_open_container');
      (containerBlock as any).initSvg();

      const hasParams = (this as any).getInput('MIMIC_PARAMS') !== null;
      const hasPathReplacement = (this as any).getInput('PATH_REPLACEMENT') !== null;

      (containerBlock as any).setFieldValue(hasParams ? 'TRUE' : 'FALSE', 'HAS_PARAMS');
      (containerBlock as any).setFieldValue(
        hasPathReplacement ? 'TRUE' : 'FALSE',
        'HAS_PATH_REPLACEMENT'
      );

      return containerBlock;
    },

    compose: function (
      this: Blockly.Block,
      containerBlock: Blockly.Block
    ) {
      const hasParams = (containerBlock as any).getFieldValue('HAS_PARAMS') ===
        'TRUE';
      const hasPathReplacement =
        (containerBlock as any).getFieldValue('HAS_PATH_REPLACEMENT') === 'TRUE';

      (this as any).updateShape_(hasParams, hasPathReplacement);
    },
  };

  const mimicOpenOverlayMutator = {
    mutationToDom: function (this: Blockly.Block) {
      const container = Blockly.utils.xml.createElement('mutation');
      const hasParams = (this as any).getInput('MIMIC_PARAMS') !== null;
      const hasPathReplacement = (this as any).getInput('PATH_REPLACEMENT') !== null;
      container.setAttribute('has_params', hasParams ? 'true' : 'false');
      container.setAttribute(
        'has_path_replacement',
        hasPathReplacement ? 'true' : 'false'
      );
      return container;
    },

    domToMutation: function (this: Blockly.Block, xmlElement: Element) {
      const hasParams = xmlElement.getAttribute('has_params') === 'true';
      const hasPathReplacement =
        xmlElement.getAttribute('has_path_replacement') === 'true';
      (this as any).updateShape_(hasParams, hasPathReplacement);
    },

    updateShape_: function (
      this: Blockly.Block,
      hasParams: boolean,
      hasPathReplacement: boolean
    ) {
      // 移除现有的参数和变量目录替换输入（如果存在）
      if ((this as any).getInput('MIMIC_PARAMS')) {
        (this as any).removeInput('MIMIC_PARAMS');
      }
      if ((this as any).getInput('PATH_REPLACEMENT')) {
        (this as any).removeInput('PATH_REPLACEMENT');
      }

      // 如果需要参数，添加输入
      if (hasParams) {
        (this as any).appendValueInput('MIMIC_PARAMS')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     画面参数:');
      }

      // 如果需要变量目录替换，添加输入
      if (hasPathReplacement) {
        (this as any).appendValueInput('PATH_REPLACEMENT')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     变量目录替换:');
      }
    },

    decompose: function (this: Blockly.Block, workspace: Blockly.Workspace) {
      const containerBlock = workspace.newBlock('mimic_open_overlay_container');
      (containerBlock as any).initSvg();

      const hasParams = (this as any).getInput('MIMIC_PARAMS') !== null;
      const hasPathReplacement = (this as any).getInput('PATH_REPLACEMENT') !== null;

      (containerBlock as any).setFieldValue(hasParams ? 'TRUE' : 'FALSE', 'HAS_PARAMS');
      (containerBlock as any).setFieldValue(
        hasPathReplacement ? 'TRUE' : 'FALSE',
        'HAS_PATH_REPLACEMENT'
      );

      return containerBlock;
    },

    compose: function (
      this: Blockly.Block,
      containerBlock: Blockly.Block
    ) {
      const hasParams = (containerBlock as any).getFieldValue('HAS_PARAMS') ===
        'TRUE';
      const hasPathReplacement =
        (containerBlock as any).getFieldValue('HAS_PATH_REPLACEMENT') === 'TRUE';

      (this as any).updateShape_(hasParams, hasPathReplacement);
    },
  };

  const mimicOpenPopupMutator = {
    mutationToDom: function (this: Blockly.Block) {
      const container = Blockly.utils.xml.createElement('mutation');
      const hasParams = (this as any).getInput('MIMIC_PARAMS') !== null;
      const hasPathReplacement = (this as any).getInput('PATH_REPLACEMENT') !== null;
      container.setAttribute('has_params', hasParams ? 'true' : 'false');
      container.setAttribute(
        'has_path_replacement',
        hasPathReplacement ? 'true' : 'false'
      );
      return container;
    },

    domToMutation: function (this: Blockly.Block, xmlElement: Element) {
      const hasParams = xmlElement.getAttribute('has_params') === 'true';
      const hasPathReplacement =
        xmlElement.getAttribute('has_path_replacement') === 'true';
      (this as any).updateShape_(hasParams, hasPathReplacement);
    },

    updateShape_: function (
      this: Blockly.Block,
      hasParams: boolean,
      hasPathReplacement: boolean
    ) {
      // 移除现有的参数和变量目录替换输入（如果存在）
      if ((this as any).getInput('MIMIC_PARAMS')) {
        (this as any).removeInput('MIMIC_PARAMS');
      }
      if ((this as any).getInput('PATH_REPLACEMENT')) {
        (this as any).removeInput('PATH_REPLACEMENT');
      }

      // 如果需要参数，添加输入
      if (hasParams) {
        (this as any).appendValueInput('MIMIC_PARAMS')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     画面参数:');
      }

      // 如果需要变量目录替换，添加输入
      if (hasPathReplacement) {
        (this as any).appendValueInput('PATH_REPLACEMENT')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     变量目录替换:');
      }
    },

    decompose: function (this: Blockly.Block, workspace: Blockly.Workspace) {
      const containerBlock = workspace.newBlock('mimic_open_popup_container');
      (containerBlock as any).initSvg();

      const hasParams = (this as any).getInput('MIMIC_PARAMS') !== null;
      const hasPathReplacement = (this as any).getInput('PATH_REPLACEMENT') !== null;

      (containerBlock as any).setFieldValue(hasParams ? 'TRUE' : 'FALSE', 'HAS_PARAMS');
      (containerBlock as any).setFieldValue(
        hasPathReplacement ? 'TRUE' : 'FALSE',
        'HAS_PATH_REPLACEMENT'
      );

      return containerBlock;
    },

    compose: function (
      this: Blockly.Block,
      containerBlock: Blockly.Block
    ) {
      const hasParams = (containerBlock as any).getFieldValue('HAS_PARAMS') ===
        'TRUE';
      const hasPathReplacement =
        (containerBlock as any).getFieldValue('HAS_PATH_REPLACEMENT') === 'TRUE';

      (this as any).updateShape_(hasParams, hasPathReplacement);
    },
  };

  const mimicPreloadMutator = {
    mutationToDom: function (this: Blockly.Block) {
      const container = Blockly.utils.xml.createElement('mutation');
      const hasParams = (this as any).getInput('MIMIC_PARAMS') !== null;
      const hasPathReplacement = (this as any).getInput('PATH_REPLACEMENT') !== null;
      const hasMaxCount = (this as any).getInput('MAX_COUNT') !== null;

      container.setAttribute('has_params', hasParams ? 'true' : 'false');
      container.setAttribute(
        'has_path_replacement',
        hasPathReplacement ? 'true' : 'false'
      );
      container.setAttribute('has_max_count', hasMaxCount ? 'true' : 'false');

      return container;
    },

    domToMutation: function (this: Blockly.Block, xmlElement: Element) {
      const hasParams = xmlElement.getAttribute('has_params') === 'true';
      const hasPathReplacement =
        xmlElement.getAttribute('has_path_replacement') === 'true';
      const hasMaxCount = xmlElement.getAttribute('has_max_count') === 'true';

      (this as any).updateShape_(hasParams, hasPathReplacement, hasMaxCount);
    },

    updateShape_: function (
      this: Blockly.Block,
      hasParams: boolean,
      hasPathReplacement: boolean,
      hasMaxCount: boolean
    ) {
      // 移除现有的输入（如果存在）
      if ((this as any).getInput('MIMIC_PARAMS')) {
        (this as any).removeInput('MIMIC_PARAMS');
      }
      if ((this as any).getInput('PATH_REPLACEMENT')) {
        (this as any).removeInput('PATH_REPLACEMENT');
      }
      if ((this as any).getInput('MAX_COUNT')) {
        (this as any).removeInput('MAX_COUNT');
      }

      // 如果需要参数，添加输入
      if (hasParams) {
        (this as any).appendValueInput('MIMIC_PARAMS')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     画面参数:');
      }

      // 如果需要变量目录替换，添加输入
      if (hasPathReplacement) {
        (this as any).appendValueInput('PATH_REPLACEMENT')
          .setCheck('Array')
          .setAlign(1)
          .appendField('                                     变量目录替换:');
      }

      // 如果需要最大预加载数量，添加输入
      if (hasMaxCount) {
        (this as any).appendValueInput('MAX_COUNT')
          .setCheck('Number')
          .setAlign(1)
          .appendField('                                     最大预加载数量:');
      }
    },

    decompose: function (this: Blockly.Block, workspace: Blockly.Workspace) {
      const containerBlock = workspace.newBlock('mimic_preload_container');
      (containerBlock as any).initSvg();

      const hasParams = (this as any).getInput('MIMIC_PARAMS') !== null;
      const hasPathReplacement = (this as any).getInput('PATH_REPLACEMENT') !== null;
      const hasMaxCount = (this as any).getInput('MAX_COUNT') !== null;

      (containerBlock as any).setFieldValue(hasParams ? 'TRUE' : 'FALSE', 'HAS_PARAMS');
      (containerBlock as any).setFieldValue(
        hasPathReplacement ? 'TRUE' : 'FALSE',
        'HAS_PATH_REPLACEMENT'
      );
      (containerBlock as any).setFieldValue(
        hasMaxCount ? 'TRUE' : 'FALSE',
        'HAS_MAX_COUNT'
      );

      return containerBlock;
    },

    compose: function (
      this: Blockly.Block,
      containerBlock: Blockly.Block
    ) {
      const hasParams = (containerBlock as any).getFieldValue('HAS_PARAMS') ===
        'TRUE';
      const hasPathReplacement =
        (containerBlock as any).getFieldValue('HAS_PATH_REPLACEMENT') === 'TRUE';
      const hasMaxCount =
        (containerBlock as any).getFieldValue('HAS_MAX_COUNT') === 'TRUE';

      (this as any).updateShape_(hasParams, hasPathReplacement, hasMaxCount);
    },
  };

  const utilsRedirectMutator = {
    mutationToDom: function (this: Blockly.Block) {
      const container = Blockly.utils.xml.createElement('mutation');
      const hasNewTabOption = (this as any).getField('NEW_TAB') !== null;
      container.setAttribute(
        'has_new_tab_option',
        hasNewTabOption ? 'true' : 'false'
      );
      return container;
    },

    domToMutation: function (this: Blockly.Block, xmlElement: Element) {
      const hasNewTabOption =
        xmlElement.getAttribute('has_new_tab_option') === 'true';
      (this as any).updateShape_(hasNewTabOption);
    },

    updateShape_: function (this: Blockly.Block, hasNewTabOption: boolean) {
      // 移除现有的新窗口选项（如果存在）
      if ((this as any).getField('NEW_TAB')) {
        (this as any).removeInput('NEW_TAB_INPUT');
      }

      // 如果需要新窗口选项，添加输入
      if (hasNewTabOption) {
        (this as any).appendDummyInput('NEW_TAB_INPUT')
          .setAlign(1)
          .appendField('                                     在新窗口打开:')
          .appendField(
            new Blockly.FieldDropdown([
              ['是', 'true'],
              ['否', 'false'],
            ]),
            'NEW_TAB'
          );
      }
    },

    decompose: function (this: Blockly.Block, workspace: Blockly.Workspace) {
      const containerBlock = workspace.newBlock('utils_redirect_container');
      (containerBlock as any).initSvg();

      const hasNewTabOption = (this as any).getField('NEW_TAB') !== null;
      (containerBlock as any).setFieldValue(
        hasNewTabOption ? 'TRUE' : 'FALSE',
        'HAS_NEW_TAB_OPTION'
      );

      return containerBlock;
    },

    compose: function (
      this: Blockly.Block,
      containerBlock: Blockly.Block
    ) {
      const hasNewTabOption =
        (containerBlock as any).getFieldValue('HAS_NEW_TAB_OPTION') === 'TRUE';
      (this as any).updateShape_(hasNewTabOption);
    },
  };

  // 只注册一次变异器
  if (!mutatorsRegistered) {
    try {
      // 注册所有变异器
      Blockly.Extensions.registerMutator(
        'system_variable_set_value_mutator',
        setValueMutator
      );
      Blockly.Extensions.registerMutator(
        'system_logger_log_mutator',
        loggerLogMutator
      );
      Blockly.Extensions.registerMutator(
        'system_mimic_open_mutator',
        mimicOpenMutator
      );
      Blockly.Extensions.registerMutator(
        'system_mimic_open_overlay_mutator',
        mimicOpenOverlayMutator
      );
      Blockly.Extensions.registerMutator(
        'system_mimic_open_popup_mutator',
        mimicOpenPopupMutator
      );
      Blockly.Extensions.registerMutator(
        'system_mimic_preload_mutator',
        mimicPreloadMutator
      );
      Blockly.Extensions.registerMutator(
        'system_utils_redirect_mutator',
        utilsRedirectMutator
      );
      
      mutatorsRegistered = true;
      console.log('All system function mutators registered successfully');
    } catch (e) {
      console.warn('Error registering mutators, they may already be registered:', e);
    }
  }
}
